package com.markhsiu.result;

import java.io.BufferedReader;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @author Mark Hsiu
 * @since 2018/8/5 下午6:05
 */
public abstract class DataAbsract {


    public static final int T = 98;

    // 静态数据
    protected int n;                  // app数
    protected int N;                  // inst数
    protected int m;                  // machine数
    protected int k;                  // 资源种类
    protected List<Integer> cpuIter;            // T个时刻的cpu资源


    protected Map<Integer, Integer> inst2AppIndex;
    protected double[][] appResources;
    protected double[][] machineResources;
    protected Map<Integer, Integer>[] appInterference;

    // 动态数据
    protected Map<Integer, Integer> inst2Machine;
    protected volatile double[][] machineResourcesUsed;
    protected Map<Integer, Integer>[] machineHasApp;

    protected abstract boolean toMachine(int appIt, int inst, int machineIt);

    protected abstract boolean toMachine(int appIt, int inst, int machineIt, boolean doCheck);

    // 读取数据
    public void init(BufferedReader bufferedReader) throws IOException {
        /* Preprocessing: cat *.csv to one file as:
               n
               a_app_resources.csv
               m
               a_machine_resources.csv
               N
               a_instance_deploy.csv
               iterference_cnt
               a_app_interference.csv
            judge framework
        */
        /** cpuIter */
        cpuIter = new ArrayList<Integer>();
        for (int i = 0; i < T; i++) {
            cpuIter.add(i);
        }
        /** Read app_resources */
        n = Integer.parseInt(bufferedReader.readLine());

        for (int i = 0; i < n; i++) {
            // appId,resources
            String line = bufferedReader.readLine();
            String[] parts = line.split(",", -1);
            List<Double> resources = new ArrayList<Double>();
            for (String x : parts[1].split("\\|", -1)) {
                resources.add(Double.parseDouble(x));
            }
            for (String x : parts[2].split("\\|", -1)) {
                resources.add(Double.parseDouble(x));
            }
            for (int j = 3; j < parts.length; j++) {
                resources.add(Double.parseDouble(parts[j]));
            }
            if (i == 0) {
                k = resources.size();
                appResources = new double[n][k];
            }

            for (int j = 0; j < k; j++) {
                appResources[i][j] = resources.get(j);
            }
        }

        /** Read machine_resources*/
        m = Integer.parseInt(bufferedReader.readLine());
        machineResources = new double[m][k];
        machineResourcesUsed = new double[m][k];

        machineHasApp = new Map[m];

        List<String> machineList = new ArrayList<>();
        for(int i = 0; i < m; i++){
            String line = bufferedReader.readLine();
            machineList.add(line);
        }

        for (int i = 0; i < m; i++) {
            // machineId,resources
            //优先使用大磁盘资源的机器
            String line = machineList.get(i);
            String[] parts = line.split(",", -1);

            machineHasApp[i] = new HashMap<Integer, Integer>();
            double cpu = Double.parseDouble(parts[1]);
            double mem = Double.parseDouble(parts[2]);
            for (int j = 0; j < T; j++) {
                machineResources[i][j] = cpu;
                machineResources[i][T + j] = mem;
            }
            for (int j = 3; j < parts.length; j++) {
                machineResources[i][2 * T + j - 3] = Double.parseDouble(parts[j]);
            }
            for (int j = 0; j < k; j++) {
                machineResourcesUsed[i][j] = 0.;
            }
        }

        /** Read instance_deploy */
        N = Integer.parseInt(bufferedReader.readLine());
        inst2AppIndex = new HashMap<>();
        inst2Machine = new HashMap<>();
        for (int i = 0; i < N; i++) {
            String line = bufferedReader.readLine();
            String[] parts = line.split(",", -1);

            int instInt = Integer.parseInt(parts[0].substring("inst_".length())) -1;
            int appInt = Integer.parseInt(parts[1].substring("app_".length())) -1;

            inst2AppIndex.put(instInt, appInt);
            if (!"".equals(parts[2])) {
                int machineInt = Integer.parseInt(parts[2].substring("machine_".length())) -1;
                toMachine(appInt,instInt, machineInt, false);
            }
        }

        /** Read app_interference */
        int icnt = Integer.parseInt(bufferedReader.readLine());
        appInterference = new Map[n];
        for (int i = 0; i < n; i++) {
            appInterference[i] = new HashMap<>();
        }
        for (int i = 0; i < icnt; i++) {
            String line = bufferedReader.readLine();
            String[] parts = line.split(",", -1);


            int app1 = Integer.parseInt(parts[0].substring("app_".length())) -1;
            int app2 = Integer.parseInt(parts[1].substring("app_".length())) -1;
            int limit = Integer.parseInt(parts[2]);
            Map<Integer, Integer> inter = appInterference[app1];

            if (app1 == app2) {
                limit += 1; //self-interference +1 here
            }
            inter.put(app2, limit);
        }
    }


}
